package com.demo2do.fms.admin.web.controller.business;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.utils.DateFormatUtils;
import com.demo2do.core.web.interceptor.MenuSetting;
import com.demo2do.core.web.utils.WebUtils;
import com.demo2do.fms.admin.entity.export.business.ExpenseSheet;
import com.demo2do.fms.admin.entity.search.business.ExpenseSheetSearch;
import com.demo2do.fms.admin.entity.security.Login;
import com.demo2do.fms.admin.service.authority.OrganizationService;
import com.demo2do.fms.admin.service.business.ExpenseSheetService;
import com.demo2do.fms.admin.utils.FormatUtils;
import com.demo2do.fms.admin.web.resolver.Secure;
import com.demo2do.fms.admin.web.view.ExcelTemplateView;
import com.demo2do.fms.entity.authority.Organization;

/**
 * 打印报销单、设置内部加油量
 *
 * @author Ark
 *
 */
@Controller
@RequestMapping("/expense-sheets")
@MenuSetting("menu-business")
public class ExpenseSheetController {
    
    private static final Logger logger = LoggerFactory.getLogger(ExpenseSheetController.class);
    
    @Autowired
    private ExpenseSheetService expenseSheetService;
    
    @Autowired
    private OrganizationService organizationService;
    
    /**
     * 打印报销单 - search panel
     * 
     * @param login
     * @return
     */
    @RequestMapping(value = "/search", method = RequestMethod.GET)
    @MenuSetting("submenu-expense-sheet")
    public ModelAndView search(@Secure Login login) {
        
        ModelAndView modelAndView = new ModelAndView("business/expense-sheet/expense-sheet-search");
        
        modelAndView.addObject("region", login.isRegionUser());
        modelAndView.addObject("orgIds", login.getCurrOrgIds());
        
        return modelAndView;
        
    }
    
    /**
     * 打印报销单 - on search
     * 
     * @param request
     * @param search
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET, params = "filter")
    @MenuSetting("submenu-expense-sheet")
    public ModelAndView onSearch(ExpenseSheetSearch search, HttpServletRequest request) {
        
        ModelAndView modelAndView = new ModelAndView("business/expense-sheet/expense-sheet-list");
        
        int totals = expenseSheetService.countDispatchOrderRecord(search);
        if (totals > 0) {
            
            List<Map<String, Object>> result = expenseSheetService.listDispatchOrderRecord(search);
            
            for(Map<String, Object> item : result) {
                item.put("idString", String.valueOf(item.get("id")));
            }
            
            modelAndView.addObject("result", result);
            modelAndView.addObject("selectDispatchOrderIds", search.getSelectDispatchOrderIds());
            modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "page", "filter"));

        }
        
        return modelAndView;
        
    }
    
    /**
     * 设置内部加油量 - prepare
     * 
     * @param dispatchOrderIds
     * @return
     */
    @RequestMapping(value = "/setup-oils", method = RequestMethod.GET)
    @MenuSetting("submenu-expense-sheet")
    public ModelAndView setupOils(@RequestParam("dispatchOrderIds") List<Long> dispatchOrderIds) {
        
        ModelAndView modelAndView = new ModelAndView("business/expense-sheet/expense-sheet-set-oils");
        
        BigDecimal ratedOilUsage = expenseSheetService.getInternalOils(dispatchOrderIds);
        
        modelAndView.addObject("dispatchOrderIds",dispatchOrderIds);
        modelAndView.addObject("ratedOilUsage", ratedOilUsage);
        
        return modelAndView;
        
    }
    
    /**
     * 设置内部加油量 - on setup
     * 
     * @param operator
     * @param dispatchOrderIds
     * @param ratedOilUsage
     * @param actualOilUsage
     * @return
     */
    @RequestMapping(value = "/setup-oils", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @MenuSetting("submenu-expense-sheet")
    public @ResponseBody HttpResult onSetupOils(@Secure(property = "id") Long operator,
                                                @RequestParam("dispatchOrderIds") List<Long> dispatchOrderIds,
                                                @RequestParam("ratedOilUsage") BigDecimal ratedOilUsage,
                                                @RequestParam("actualOilUsage") BigDecimal actualOilUsage) {

        HttpResult httpResult = new HttpResult();
        
        try {
            
            // setup oil usage for checked orders
            BigDecimal actualOilUsageReal = ratedOilUsage.subtract(actualOilUsage);
            expenseSheetService.setupInternalOils(dispatchOrderIds, ratedOilUsage, actualOilUsageReal, operator);
            
            httpResult.success().message("设置油量成功");
            
        } catch (Exception e) {
            httpResult.fail("500").message("设置油量失败");
            logger.error("#onSetupOilUsage() - set oil usage fail, exception is [{}]", e);
        }
        
        return httpResult;
        
    }
    
    /**
     * 打印油费 - panel
     * 
     * @return
     */
    @RequestMapping(value = "/export-oil-price", method = RequestMethod.GET)
    public String exportOilPrice() {
        return "business/expense-sheet/expense-sheet-export-oil-price";
    }
    
    /**
     * 打印油费
     * 
     * @param dispatchOrderIds
     * @return
     */
    @RequestMapping(value = "/export-oil-price", method = RequestMethod.POST)
    public ModelAndView onExportOilPrice(@RequestParam("dispatchOrderIds") List<Long> dispatchOrderIds) {
        
        ModelAndView modelAndView = new ModelAndView(new ExcelTemplateView("business/oil-price.xls"));
        
        // 1. list result
        if(dispatchOrderIds.size() > 33) {
            dispatchOrderIds = dispatchOrderIds.subList(0, 33);
        }
        
        List<Map<String, Object>> results = expenseSheetService.listOilPrice(dispatchOrderIds);
        modelAndView.addObject("results", results);
        
        if(!results.isEmpty()) {
            
            // 2. 车号
            modelAndView.addObject("vehicleCode", results.get(0).get("vehicleCode"));
            
            // 3. get oilPrice sequence
            Long organizationId = Long.parseLong(results.get(0).get("organizationId").toString());
            Organization organization = organizationService.load(Organization.class, organizationId);
            String sequence = expenseSheetService.getOilPriceSequence(organization.getCode());
            modelAndView.addObject("sequence", sequence);
            
            // 4. date today
            String today = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
            modelAndView.addObject("today", today);
            
        }
        
        return modelAndView;
        
    }
    
    /**
     * 打印报销单 - 提示页
     * 
     * @return
     */
    @RequestMapping(value = "/export", method = RequestMethod.GET)
    public String export() {
        return "business/expense-sheet/expense-sheet-export";
    }
    
    /**
     * 打印报销单
     * 
     * @param operator
     * @param dispatchOrderIds
     * @return
     */
    @RequestMapping(value = "/export", method = RequestMethod.POST)
    public ModelAndView onExport(@Secure(property = "id") Long operator, 
                                 @RequestParam("dispatchOrderIds") List<Long> dispatchOrderIds) {
        
        ModelAndView modelAndView = new ModelAndView(new ExcelTemplateView("business/expense-sheet.xls"));
        
        logger.warn("#onExport() - export order, size=[{}]", dispatchOrderIds.size());
        
        // 1. 构造报销单对象列表
        List<ExpenseSheet> expenseSheets = expenseSheetService.listExpenseSheet(dispatchOrderIds, operator);
        modelAndView.addObject("expenseSheets", expenseSheets);
        
        // 2. 日期格式化对象
        FormatUtils fmt = new FormatUtils();
        modelAndView.addObject("fmt", fmt);
        
        return modelAndView;
        
    }
    
}
